local meta = FindMetaTable("Player")
if not meta then return end

function meta:RemoveHoverGear()
	for _, ent in pairs(ents.FindByClass("vehicle*")) do
		if ent:GetVehicleOwner() == self then
			ent:Remove()
			self:UnSpectate()
		end
	end
end

function meta:SpawnHoverGear(pos, ang)
	self:RemoveHoverGear()

	pos = pos or (self:GetPos() + Vector(0, 0, 16))
	if not ang then
		ang = self:GetAngles()
		ang:RotateAroundAxis(Vector(0, 0, 1), 270)
	end

	local vehicle = ents.Create(GAMEMODE.VehicleClass)
	if vehicle:IsValid() then
		vehicle:SetPos(pos)
		vehicle:Spawn()
		vehicle:SetAngles(ang)
		vehicle:SetVehicleOwner(self)

		self:SetHoverGear(vehicle)
		self:Spectate(OBS_MODE_CHASE)
		self:SpectateEntity(vehicle)
	end

	return vehicle
end

function meta:UpdateGameState()
	GAMEMODE:UpdateGameState(self)
end

function meta:EnterQueue(silent)
	if not self:IsInQueue() then
		table.insert(GAMEMODE.Queue, self)
		if not silent then
			self:PrintMessage(HUD_PRINTTALK, "You have been entered in to the racing queue!")
		end

		GAMEMODE:UpdateQueue()
	end
end

function meta:ExitQueue(silent)
	local slot = self:IsInQueue()
	if slot then
		table.remove(GAMEMODE.Queue, slot)
		if not silent then
			self:PrintMessage(HUD_PRINTTALK, "You have been removed from the racing queue!")
		end

		GAMEMODE:UpdateQueue()

		return slot
	end
end

function meta:RemoveAllStatus(bSilent, bInstant)
	if bInstant then
		for _, ent in pairs(ents.FindByClass("status_*")) do
			local owner =  ent:GetOwner()
			if owner:IsValid() and not ent.NoRemoveOnDeath and owner:GetOwner() == self then
				ent:Remove()
			end
		end
	else
		for _, ent in pairs(ents.FindByClass("status_*")) do
			local owner =  ent:GetOwner()
			if owner:IsValid() and not ent.NoRemoveOnDeath and owner:GetOwner() == self then
				ent.SilentRemove = bSilent
				ent:SetDie()
			end
		end
	end
end

function meta:RemoveStatus(sType, bSilent, bInstant, sExclude)
	local removed
	for _, ent in pairs(ents.FindByClass("status_"..sType)) do
		if sExclude and ent:GetClass() ~= sExclude then
			local owner = ent:GetOwner()
			if owner:IsValid() and owner:GetOwner() == self then
				if bInstant then
					ent:Remove()
				else
					ent.SilentRemove = bSilent
					ent:SetDie()
				end
				removed = true
			end
		end
	end
	return removed
end

function meta:GetStatus(sType)
	local ent = self["status_"..sType]
	if ent and ent.Owner == self then return ent end
end

function meta:GiveStatus(sType, fDie)
	local cur = self:GetStatus(sType)
	if cur then
		cur:SetPlayer(self, true)
		if fDie then
			cur:SetDie(fDie)
		end
		return cur
	else
		local ent = ents.Create("status_"..sType)
		if ent:IsValid() then
			ent:Spawn()
			ent:SetPlayer(self)
			if fDie then
				ent:SetDie(fDie)
			end
			return ent
		end
	end
end
meta.Give = meta.GiveStatus